package com.example.auth.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.security.Principal;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Classname AuthController
 * @Description TODO
 * @Date 2022/5/13 17:11
 * @Created by XiongXiong
 * @Author: X.I.O
 */

@RestController
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private TokenEndpoint tokenEndpoint;

    Logger logger = LoggerFactory.getLogger(AuthController.class);

    @RequestMapping(value = "/users/current", method = RequestMethod.GET)
    public Principal getUser(Principal principal) {
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>");
        logger.info(principal.toString());
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>");
        return principal;
    }


    @RequestMapping("/login")
    public ResponseEntity<?> login() throws HttpRequestMethodNotSupportedException {
        // 1. 使用用户名和密码创建Authentication对象
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                "user_1",
                "123456"
        );

        // 2. 调用AuthenticationManager进行认证
        //    这里会触发你的UserDetailsService加载用户和密码比对
        Authentication authentication = authenticationManager.authenticate(authRequest);

        // 3. 手动创建OAuth2的Token请求
        //    模拟一个OAuth2的密码模式请求，以便利用现有的Token生成流程
        TokenRequest tokenRequest = new TokenRequest(
                Collections.singletonMap("client_id", "client-app"), // 你的客户端ID
                "client-app", // 客户端ID
                Sets.newHashSet("all"), // 范围
                "password" // 授权类型
        );

        OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetailsService.loadClientByClientId("client-app"));
        OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);

        // 4. 委托给TokenEndpoint来生成Token（这会应用我们的CustomTokenEnhancer）
        ResponseEntity<OAuth2AccessToken> tokenResponse = tokenEndpoint.postAccessToken(oAuth2Authentication, Collections.emptyMap());

        // 5. 获取标准的Token响应，并包装成你自己的格式
        OAuth2AccessToken body = tokenResponse.getBody();

        // 6. 构建自定义的成功响应体
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("code", 200); // 自定义状态码
        result.put("message", "登录成功"); // 自定义信息
        result.put("data", body); // 标准的Token信息

        return ResponseEntity.ok(result);
    }

}
